package com.linkai.JUC._13_future;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @Description: CompletableFuture 异步调用 类似Ajax
 *                  1. 异步执行：进行异步回调之后，不需要等获得结果，原来的程序可以继续执行下去
 *                  2. 成功回调
 *                  3. 失败回调
 *                可以用 CompletableFuture 做很多多线程任务，并且拿到结果
 * @Author: 林凯
 * @Date: 2021/10/25 19:25
 */
public class CompletableFutureTest01 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 发起一个请求
        //没有返回值的 runAsync 异步回调，泛型里面写 Void
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "runAsync 异步回调");
        });

        voidCompletableFuture.get();    // 获取阻塞执行结果

        // 有返回值的 supplyAsync 异步回调
        // 这里的 supply 很好记，对应的就是 Supplier 接口：供给型接口（函数接口那部分有讲）
        // ajax 成功和失败的回调；失败的回调返回的是错误的信息
        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "supplyAsync 异步回调");
//            int i = 10/0;   // 除0异常
            return 1024;
        });

        // 链式编程
        Integer integer = integerCompletableFuture
                // 根据回调执行的结果，进入不同的方法执行。
                // 成功回调时
                .whenCompleteAsync((t, u) -> {
                    System.out.println("t=> " + t);     // 正常的返回结果
                    System.out.println("u=> " + u);     // 错误信息
                })
                // 失败回调时
                .exceptionally((e) -> {
                    System.out.println(e.getMessage());
                    return 404;
                })
                // 最后获取一个结果
                .get();

        System.out.println("最终回调结果：" + integer);

    }
}
